function getSum (a, b, c) {
    return a + b + c
}

const checkAge = (min) => {
    return function (age) {
        return age > min
    }
}
const checkAge18 = checkAge(18)
// console.log(checkAge18(15))

// const curried = curry(getSum)
// console.log(curried(1, 2, 3))
// console.log(curried(1, 2)(3))
// console.log(curried(1)(2)(3))


function curry (func) {
    return function curriedFn(...args) {
        if (args.length < func.length) {
            return function () {
                return curriedFn(...args.concat(Array.from(arguments)))
            }
        }
        return func(...args)
    }
} 


// let list = [3, 2, 1, 5, 4]
// let k = 3

// const add = (num) => {
//     list.push(num)
//     const _list = list.sort((a, b) => {
//         return b - a
//     })
//     console.log(_list)

//     console.log(_list[k - 1])
// }

// add(6) // => 4
// add(7) // => 5
// add(0) // => 5
// add(9) // => 6


// function add () {
//     let _args = Array.prototype.slice.call(arguments)

//     let _adder = function () {
//         _args.push(...arguments)
//         return _adder
//     }

//     _adder.toString = function () {
//         return _args.reduce(function (a, b) {
//             return a + b
//         })
//     }

//     return _adder
// }


// function curry (func) {
//     return function curriedFn(...args) {
//         if (args.length < func.length) {
//             return function () {
//                 return curriedFn(...args.concat(Array.from(arguments)))
//             }
//         }
//         return func(...args)
//     }
// }
// function add () {
//     let _args = Array.prototype.slice.call(arguments)

//     const _adder = function () {
//         _args = _args.concat(...arguments)
//         return _adder
//     }
    
//     _adder.toString = function () {
//         console.log('dd')
//         return _args.reduce((a, b) => a + b)
//     }

//     return _adder
// }

// console.log(add(1)(2))
// console.log(add(1)(2)(3)); //6
// console.log(add(1)(2)(3)(4)); //10
// console.log(add(1)(2)(3)(4)(5));//15
// console.log(add(1)(2)(3)(4)(5)(6));//21



// function * generatorFn () {
//     yield 1
//     yield 2
//     yield 3
// }

// function foreach (gen) {
//     for (let value of gen()) {
//         console.log(value)
//     }
// }

// foreach(generatorFn)

// const _arr = [1, 1, 2 , 3, 3, 3, 3, 4, 6, 6, 8, 8]

// const fn = (array, target) => {
//     let counter = 0
//     let l = 0
//     let r = array.length
//     let index = 0

//     while (r >= l) {
//         if (r > l) {
//             if (array[l] === target) counter++
//             if (array[r] === target) counter++
//         } else {
//             if (array[l] === target) counter++
//         }
        
//         index++
//         l++
//         r--
//     }
//     console.log('index', index)
//     return counter
// }


const urls = ['url1', 'url2', 'url3']

const loadFn = (url) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(url)
        }, 100)
    })
}

// const loadOneByOne = async () => {
//     for (let value of urls) {
//         await loadFn(value)
//     }
// }
// loadOneByOne()
const loadOneByOne = Promise.reduce(
    (prevPromise, currentValue) => {
        prevPromise.then(() => currentValue.then(...))
    },
    Promise.resolve()
)

const loadByLimit = (urls, loadFn, limit = 3) => {
    const urlsCopy = [...urls]

    if (urlsCopy.length <= limit) {
        const promiseArray = urlIds.map(url => loadFn(url))
        return Promise.all(promiseArray)
    }

    const promiseArray = urlsCopy.splice(0, limit).map(url => loadFn(url))

    urlsCopy.reduce(
        (prevPromise, url) => {
            return prevPromise
                    .then(() => Promise.race(promiseArray))
                    .catch(error => { console.log(error) })
                    .then(
                        resolveId => {
                            // let resolveIdPostion = promiseArray.findIndex(id )
                            promiseArray.splice(resolveId, 1)
                            promiseArray.push(loadFn(url))
                        }
                    )
        },
        Promise.resolve()
    )
}

loadByLimit(urls, loadFn, 5)